package com.syr.mybatis;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.Optional;

/**
 * 查询辅助工具
 * <p>
 * P   外部传入的查询DTO
 * E  数据库对应的实体Entity
 *
 * @author sunyiran
 * @since 2021/1/14
 */
public class QueryHelper {

    /**
     * 分页查询单页最大数
     */
    private static final Integer MAX_SIZE = 500;

    /**
     * 最小开始页
     */
    private static final Integer MIN_PAGE = 0;


    /**
     * @param param
     * @param <E>
     * @return
     */
    public static <E> Page<E> convertPageQueryParam(PageQueryParam param) {

        Page<E> page = new Page<>();
        page.setCurrent(Math.max(MIN_PAGE, Optional.ofNullable(param.getCurrentPage()).orElse(MIN_PAGE)));
        page.setSize(Math.min(MAX_SIZE, Optional.ofNullable(param.getSize()).orElse(MAX_SIZE)));

        List<OrderItem> orderByList = Lists.newArrayList();

        param.getAscList().forEach(x -> orderByList.add(OrderItem.asc(x)));
        param.getDescList().forEach(x -> orderByList.add(OrderItem.desc(x)));
        page.setOrders(orderByList);
        return page;
    }


    /**
     * 获取查询构造器
     *
     * @param p
     * @param <E>
     * @param <P>
     * @return
     */
    public static <E, P> LambdaQueryWrapper<E> createWrapper(P p) {
        List<QueryCompare> queryCompares = QueryCompareContext.listQueryCompare(p.getClass());
        QueryWrapper<E> queryWrapper = new QueryWrapper<>();
        for (QueryCompare queryCompare : queryCompares) {
            QueryCompareContext.queryComparePolicyMap.get(queryCompare.getQueryComparePolicyEnum())
                    .addCompare(queryWrapper, queryCompare, p);
        }

        return queryWrapper.lambda();
    }


    /**
     * 分页查询
     *
     * @param mapper
     * @param p
     * @param <E>
     * @param <P>
     * @return
     */
    public static <E, P extends PageQueryParam> IPage<E> selectPage(BaseMapper<E> mapper, P p) {
        return mapper.selectPage(convertPageQueryParam(p), createWrapper(p));
    }


    /**
     * 查询多个对象
     *
     * @param mapper
     * @param p
     * @param <E>
     * @param  <P>
     * @return
     */
    public static <E, P> List<E> selectList(BaseMapper<E> mapper, P p) {
        return mapper.selectList(createWrapper(p));
    }
}
